const net = require("net")
const assert = require("assert")

// const host = "smtp.chinatelecom.cn"
// const port = 465
const host = "smtp.qq.com"
const port = 587

const user = "yaoxuu@qq.com"
const to = "yaox09@chinatelecom.cn"
const password = "yaoxu.122414"
const authCode = "jwwwwyedcsvvdicd"
let data = null
const client = net.createConnection({ host, port }, async () => {
  // 'connect' 监听器。
  console.log("connected to server!")

  let code
  code = await getData()
  assert(code === 220)
  // 建立连接：发送一个 HELO/EHLO 开头的指令
  sendData("HELO " + host)

  code = await getData()
  assert(code === 250)
  // 登录
  sendData("auth login")

  code = await getData()
  assert(code === 334)
  // 输入邮箱
  sendData(new Buffer(user).toString("base64"))

  code = await getData()
  assert(code === 334)
  // 输入授权码
  sendData(new Buffer(authCode).toString("base64"))

  code = await getData()
  assert(code === 235)
  // 发件人邮箱
  sendData(`mail from:<${user}>`)

  code = await getData()
  assert(code === 250)
  // 收件人邮箱
  sendData(`rcpt to:<${to}>`)

  code = await getData()
  assert(code === 250)
  // 我要发送数据了
  sendData(`data`)

  code = await getData()
  assert(code === 354)
  // 邮件主题
  sendData(`subject:test\n`)
  // 发件人
  sendData(`from:${user}`)
  // 收件人
  sendData(`to:${to}`)
  sendData(`cc:yaoxuu@qq.com`)
  // 正文
  sendData(`hi, I'm test!`)
  // 输入"."，表示结束
  sendData(".")

  code = await getData()
  sendData("quit")
})

function getData() {
  return new Promise((resolve, reject) => {
    next()
    function next() {
      if (data) {
        console.log("code:", data)
        let temp = data
        data = null
        resolve(temp)
      } else {
        setTimeout(next, 0)
      }
    }
  })
}

function sendData(msg) {
  console.log("发送：" + msg)
  client.write(msg + "\r\n")
}

function getCode(data) {
  return +data.toString().substr(0, 3)
}

client.on("data", res => {
  console.log("接收：", res.toString())
  data = getCode(res)
  // client.end()
})

client.on("end", () => {
  console.log("disconnected from server")
})

/**
 * 220 服务就绪 
 * 221 服务关闭传输信道 
 * 235 用户验证成功 
 * 250 要求的邮件操作完成
 * 334 等待用户输入验证信息
 * 354 开始邮件输入，以.结束
 * 421 服务未就绪，关闭传输信道
 * 503 错误的命令序列
 * 535 用户验证失败
 * 550 要求的邮件操作未完成，邮箱不可用（例如，邮箱未找到，或不可访问）
   参考文档：smtp的底层协议发送邮件-吴老-光荣之路
 */
